package com.chenjt.customizePage;

import com.chenjt.customizePage.authentication.AuthenticationFailureHandler;
import com.chenjt.customizePage.authentication.AuthenticationSuccessHandler;
import com.chenjt.customizePage.imageCode.ImageCodeSecurityConfig;
//import com.chenjt.customizePage.smsCode.SmsCodeAuthenticationSecurityConfig;
import com.chenjt.customizePage.smsCode.SmsCodeAuthenticationSecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import springfox.documentation.annotations.ApiIgnore;

import javax.sql.DataSource;

/**
 * 注释：
 *
 * @author chenjt
 * @date 2025/1/24 9:22
 */
@Configuration
public class CustomizePageSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;

    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;

    @Autowired
    private ImageCodeSecurityConfig validateCodeSecurityConfig;

    @Autowired
    private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.formLogin()
                .loginPage("/authentication/require") // 访问根路径时会进入该接口
                /**
                 * 自定义UsernamePasswordAuthenticationFilter的处理请求路径，会走到UserDetailsService实现类的loadUserByUsername方法
                 * 用 UsernamePasswordAuthenticationFilter（默认是处理/login请求）处理页面表单的“/authentication/form”请求
                 *
                 */
                .loginProcessingUrl("/authentication/form")
                .successHandler(authenticationSuccessHandler)
                .failureHandler(authenticationFailureHandler)
                .and()
                .authorizeRequests()
                .antMatchers("/authentication/require",
                        "/login.html",
                        "/code/image",
                        "/code/sms").permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .csrf().disable();

        // 加载外置配置
        http.apply(validateCodeSecurityConfig)
                .and()
//                .apply(smsCodeAuthenticationSecurityConfig)
//                .and()
                .rememberMe()
                    .tokenRepository(persistentTokenRepository())
                    .tokenValiditySeconds(60*60)
                    .userDetailsService(userDetailsService);

        http.apply(smsCodeAuthenticationSecurityConfig);
    }


    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }


    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        return tokenRepository;
    }


}
